import { decrypt, encrypt } from '../cryptoUtils'

export interface StorageSetOptions {
  /*
   * 过期时间，单位：秒
   */
  maxAge?: number
  /*
   * 是否加密
   */
  encrypt?: boolean
}
export interface StorageGetOptions {
  /*
   * 是否解密
   */
  decrypt?: boolean
}
export default class SessionStorage {
  static get<T = string>(name: string, options?: StorageGetOptions) {
    const _expire = Number(sessionStorage.getItem(`${name}_expire`))
    if (_expire) {
      const now = Date.now() / 1000
      if (now > _expire) {
        sessionStorage.removeItem(name)
        return null
      }
    }
    let data
    if (options?.decrypt) {
      data = sessionStorage.getItem(`${name}_encrypt`)
      if (data)
        data = decrypt(data)
    }
    else {
      data = sessionStorage.getItem(name)
    }
    try {
      if (data)
        return JSON.parse(data) as T
      else return null
    }
    catch {
      return data as T
    }
  }

  static set(name: string, val: any, options?: StorageSetOptions) {
    if (typeof val !== 'string')
      val = JSON.stringify(val)

    if (options?.encrypt) {
      val = encrypt(val)
      sessionStorage.setItem(`${name}_encrypt`, val)
    }
    else {
      sessionStorage.setItem(name, val)
    }
    if (options?.maxAge && !Number.isNaN(options?.maxAge)) {
      const timeout = Date.now() / 1000
      sessionStorage.setItem(
        `${name}_expire`,
        (timeout + options.maxAge).toString(),
      )
    }
  }

  static clear() {
    sessionStorage.clear()
  }

  static remove(name: string) {
    sessionStorage.removeItem(name)
    sessionStorage.removeItem(`${name}_expire`)
    sessionStorage.removeItem(`${name}_encrypt`)
  }
}
